import sys, getopt
from os import path
from random import choice
from threading import Thread
from datetime import datetime
from Crawler import GasInfo as GI
from Database.OdbcMsAccess import MsAccess

def InsertArrival(Database: MsAccess, Params):
    Database.Execute("""SELECT 1
                        FROM arrival
                        WHERE region_code = ? AND
                              supplier_id = ? AND
                              create_date = ?""", 
                     Params = Params[:3])
    
    if Database.Cursor.fetchval() is None:
        Database.Execute("INSERT INTO arrival VALUES(?, ?, ?, ?)", 
                         NeedCommit = True, 
                         Params = Params)

def InsertSupplier(Database: MsAccess, Params):
    Database.Execute("""SELECT supplier_id
                        FROM supplier
                        WHERE supplier_id = ?""", 
                     Params = Params[0])

    if Database.Cursor.fetchval() is None:
        Database.Execute("INSERT INTO supplier VALUES(?, ?)", 
                         Params = Params)

def GetUserAgent(Database: MsAccess):
    lstUA = []
    Database.Execute("""SELECT *
                        FROM _headers""")
    
    for rHeader in Database.Cursor.fetchall():
        lstUA.append(rHeader[0])

    return lstUA

def GetRegionCode(Database: MsAccess, RegionName):
    Database.Execute("""SELECT region_code
                        FROM region
                        WHERE region_name LIKE ?""", 
                      Params = "%{}%".format(RegionName))
    
    return Database.Cursor.fetchval()

def GetCmdLine(args):
    '''
    从命令行读取输入的参数
    '''

    strCmdLne = ""

    try:
        lstOpts, lstArgs = getopt.getopt(args, "hd:")
    except getopt.GetoptError:
        print("参数错误: 应为 -d")
        sys.exit(2)

    for strOpt, strArg in lstOpts:
        if strOpt == "-h":
            print("用法: %s -d <日期>\n格式: yyyyMd 或 yyyyMMdd" % \
                 (path.basename(sys._getframe().f_code.co_filename)))
            sys.exit()
        elif strOpt == "-d":
            strCmdLne = strArg
    
    return strCmdLne

if __name__ == "__main__":
    strCreateDate = GetCmdLine(sys.argv[1:])
    
    if strCreateDate != "":
        dbMsAccess = None
        lstThread = []

        try:
            dbMsAccess = MsAccess(path.join("Database", "Gas.accdb"))
            lstUA = GetUserAgent(dbMsAccess)

            dteCreateDate = datetime.strptime(strCreateDate, "%Y%m%d")

            if dteCreateDate > datetime.now():
                print("查询日期不能大于今日!")
            else:
                strCreateDate = datetime.strftime(dteCreateDate, "%Y/%m/%d") # 规范化查询日期
                print("查询日期: %s" % strCreateDate)
                print("-" * 80)

                giCrawler = GI()
                dicResult = giCrawler.QueryByDate(strCreateDate.replace("/", ""), choice(lstUA))

                for lstData in dicResult["resultMap"].values():
                    for dicGasLNGPrice in lstData:
                        # 区域代码.
                        intRegionCode = GetRegionCode(dbMsAccess, dicGasLNGPrice["cityName"])

                        if intRegionCode is None:
                            print("找不到 <%s> 的区域代码!")
                            continue
                        else:
                            intSupplierId = int(dicGasLNGPrice["sourceNum"])    # 供应商编号.
                            intTodayPrice = int(dicGasLNGPrice["todayPrice"])   # 今日价格.
                        
                            InsertSupplier(dbMsAccess, (intSupplierId, dicGasLNGPrice["sourceName"]))
                            lstThread.append(Thread(target = InsertArrival, 
                                                    name = "城市: {0:<18}\t气源: {1:<18}\t价格: {2}".format\
                                                            (dicGasLNGPrice["cityName"], 
                                                            dicGasLNGPrice["sourceName"], 
                                                            intTodayPrice), 
                                                    args = (dbMsAccess, (intRegionCode, 
                                                                            intSupplierId, 
                                                                            dteCreateDate, 
                                                                            intTodayPrice))))
                # /* 启动用于插入到 arrival 表的线程列表. */
                for thArrival in lstThread:
                    print(thArrival.name)
                    thArrival.start()
                    thArrival.join()

                print("-" * 80)
                print("抓取完成 (>^ω^<)喵!")
        
        except Exception as e:
            print(e.args)
        finally:
            if dbMsAccess != None:
                dbMsAccess.Close()